#include "protocol.h"
#include <stdio.h>
#include <stdint.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include "devInfo.h"
#include "stdio.h"
#include "time.h"
#include "comm.h"
#include "appconfig.h"
#include "bleMaster.h"
#include <unistd.h>
#include "fcntl.h"



#define DEBUG_CLOSE_HEART    //关闭心跳信息
#define DEBUG_CLOSE_MQTT     //关闭MQTT调试信息
#define BLE_ACK_OUTIME       1000 //蓝牙超时时间

#define DBG_LEVEL DBG_INFO
#define DBG_SECTION_NAME  "protocol.c"
#include <rtdbg.h>


#define PC_UART_NAME  "uart2"

static ble_info_t ble_info = {0};

static rt_device_t  uartPC  = RT_NULL;   //PC主机

static rt_mailbox_t pcRxMail  = RT_NULL; //接收PC的
static rt_mailbox_t pcTxMail  = RT_NULL; //发送给PC的

extern void copy(const char *src, const char *dst);
 
// 辅助函数：将MAC地址格式化为字符串
void mac_to_str(const uint8_t *mac, char *str, size_t len) {
    snprintf(str, len, "%02X:%02X:%02X:%02X:%02X:%02X",
             mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
 
// 辅助函数：比较两个MAC地址是否相等
rt_bool_t mac_cmp(const uint8_t *mac1, const uint8_t *mac2) 
{
    int result;
    
    result = rt_memcmp(mac1, mac2, BLE_MAC_MAX);
    if(result == 0)
    {
      return RT_TRUE;
    }
    else
    {
      return RT_FALSE;
    }
}
 
// 添加蓝牙设备信息
rt_err_t add_ble_info(const char *name, const uint8_t *mac) {
    if (ble_info.num_devices >= BLE_MAX_NUM) 
    {
        LOG_E("Error: BLE device list is full.\n");
        return RT_ERROR;
    }
 
    // 检查MAC地址是否已存在
    for (int i = 0; i < ble_info.num_devices; i++) {
        if (mac_cmp(ble_info.data[i].mac, mac)) {
            LOG_E("Error: BLE device with this MAC address already exists.\n");
            return RT_ERROR;
        }
    }
 
    // 添加新设备信息
    rt_strncpy((char *)ble_info.data[ble_info.num_devices].name, name, BLE_NAME_MAX);
    rt_memcpy(ble_info.data[ble_info.num_devices].mac, mac, BLE_MAC_MAX);
    ble_info.num_devices++;
    LOG_I("add new%d ble Info OK",ble_info.num_devices);
    return RT_EOK;
}
 
// 删除蓝牙设备信息（通过MAC地址）
rt_err_t delete_ble_info(const uint8_t *mac) 
{
    int found_index = -1;
 
    // 查找MAC地址对应的索引
    for (int i = 0; i < ble_info.num_devices; i++) 
    {
        if (mac_cmp(ble_info.data[ble_info.num_devices].mac, mac)) 
        {
            found_index = i;
            break;
        }
    }
 
    if (found_index == -1) {
        LOG_E("Error: BLE device with this MAC address not found.\n");
        return RT_ERROR;
    }
 
    // 删除设备信息并移动后续设备
    for (int i = found_index; i < ble_info.num_devices - 1; i++) 
    {
        ble_info.data[i] = ble_info.data[i + 1];
    }
    ble_info.num_devices--;
    return RT_TRUE;
}

rt_uint8_t get_ble_info(int pos,rt_uint8_t *mac, rt_uint8_t *ssid,rt_uint8_t *num)
{
  if(pos > ble_info.num_devices)
  {
    return 2;
  }
  rt_memcpy(mac,ble_info.data[pos].mac,BLE_MAC_MAX);
  rt_memcpy(ssid,ble_info.data[pos].name,BLE_NAME_MAX);
  uint16_to_str(ble_info.num_devices, num);
  return 0;
}

 
// 打印所有蓝牙设备信息（用于测试）
void print_ble_info() 
{
    char mac_str[BLE_MAC_MAX * 3]; // 每个字节2个十六进制字符加上冒号和终止符
    for (int i = 0; i < ble_info.num_devices; i++) 
    {
        mac_to_str(ble_info.data[i].mac, mac_str, sizeof(mac_str));
        LOG_W("Device %d: Name = %s, MAC = %s\n", i, ble_info.data[i].name, mac_str);
    }
}

rt_uint16_t bleInfo_crc_get(ble_info_t *sinfo)
{
	rt_uint8_t *buf;
	rt_uint16_t crc;
	
	buf = (rt_uint8_t *)sinfo;
	crc = CRC16_MODBUS(buf, sizeof(*sinfo));

	return crc;
}


#define BLE_INFO_FILE_NAME  "blecfg.cfg"
#define BLE_INFO_BAT_NAME   "blecfg.bat"


rt_err_t save_bleInfo(void)
{
  rt_err_t result;
  int fd, size;
  rt_uint16_t crc;
  
  fd = open(BLE_INFO_FILE_NAME, O_RDWR | O_CREAT | O_TRUNC);
  if(fd >= 0)//打开成功
  {
    size = write(fd,&ble_info,sizeof(ble_info));
    crc = bleInfo_crc_get(&ble_info);
    size += write(fd,&crc,2);//些CRC
    close(fd);
    if(size == (sizeof(ble_info)+2))//写成功
    {
      rt_kprintf("sizeof(*flash) = %d\r\n",sizeof(ble_info));
      result = RT_EOK;
    }
    if(result == RT_EOK)
    {
      copy(BLE_INFO_FILE_NAME,BLE_INFO_BAT_NAME);
      LOG_W("ble config file copy ok");
    }
    else
    {
      LOG_E("save ble info fail !!!!!!");
    }
  }
  else
  {
    rt_kprintf("save %s file fail !!!\r\n",BLE_INFO_FILE_NAME);
    result = RT_ERROR;
  }

  return result;
}


rt_err_t  is_file_have(const char *name)
{
	if((access(name,0)) == 0)   
	{       
		LOG_W("文件 %s 存在",name);
		return RT_EOK;
	}  
	else  
	{       
		LOG_W("文件 %s 不存在",name);
		return RT_ERROR;
	}
}

void bleInfo_init(void)
{
  ble_info.id = 1;
  ble_info.num_devices = 0;
  for(int i=0;i<BLE_MAX_NUM;i++)
  {
    rt_memset(ble_info.data[i].mac, 0, BLE_MAC_MAX);
    rt_memset(ble_info.data[i].name, 0, BLE_NAME_MAX);
  }
  
}

void bleInfo_show(void)
{
  int i=0;
  rt_kprintf("==============%d=================\r\n",ble_info.id);
  while(ble_info.num_devices--)
  {
    rt_kprintf("bleName:%s MAC:",ble_info.data[i].name);
    rt_kprintf("%02x:%02x:%02x:%02x:%02x\r\n",ble_info.data[i].mac[0],
                                          ble_info.data[i].mac[1],
                                          ble_info.data[i].mac[2],
                                          ble_info.data[i].mac[3],
                                          ble_info.data[i].mac[4],
                                          ble_info.data[i].mac[5]);
    i++;
  }
}

rt_err_t load_bleInfo(void)
{
  rt_err_t result;
  int fd, size = 0;

  fd = open(BLE_INFO_FILE_NAME, O_RDWR);
  if(fd >= 0)//打开文件成功
  { 
    rt_uint16_t crc;
    rt_uint16_t curCrc;
    
    size += read(fd,&ble_info,sizeof(ble_info));
    size += read(fd,&crc,2);
    
    close(fd);
    if(size != sizeof(ble_info)+2)//文件错误
    {
      rt_err_t have;
      
      have = is_file_have(BLE_INFO_BAT_NAME);
      if(have == RT_EOK)
      {
        copy(BLE_INFO_BAT_NAME,BLE_INFO_FILE_NAME);
      }
      else
      {
        LOG_E("None Cfg BAT is create New Cfg");
        bleInfo_init();
        save_bleInfo();
      }
      return RT_ERROR;
    }
    curCrc = bleInfo_crc_get(&ble_info);
     if(curCrc == crc)//crc正常
    {
      result = RT_EOK;
      rt_kprintf("load %s file ok ^_^\r\n",BLE_INFO_FILE_NAME);
    }
    else
    {
      LOG_E("Load InfoCfg crc=%x != %x", crc, curCrc);
    }
    
  }
  else//文件打不开
  {
    LOG_E("ble config file open err !!!!!!!!!!");
    result = is_file_have(BLE_INFO_BAT_NAME);
    if(result == RT_EOK)
    {
      LOG_W("copy %s file to %s file",BLE_INFO_BAT_NAME,BLE_INFO_FILE_NAME);
      unlink(BLE_INFO_FILE_NAME);
      copy(BLE_INFO_BAT_NAME,BLE_INFO_FILE_NAME);
      result = RT_EEMPTY;
    }
    else
    {
      LOG_E("None Bat CFG File");
      bleInfo_init();
      save_bleInfo();
      result = RT_ERROR;
    }
    rt_kprintf("load %s file fail !!!\r\n",BLE_INFO_FILE_NAME);
    result = RT_ERROR;
  }

  return result;
}


void flash_load_bleInfo(void)
{
	rt_err_t result;
	
	result = load_bleInfo();
	
	if(result == RT_EOK)//成功
	{
		LOG_I("load devinfo file ok\r\n");
	}
	else if(result == RT_EEMPTY)//加载备份
	{
		LOG_W("start bat config file");
		result = load_bleInfo();
	}
	else
	{
		LOG_E("load devinfo file Fail\r\n");
	}

  bleInfo_show();
}



rt_err_t recv_pc_mail(pcMailDef *mail,rt_int32_t timeout)
{
	rt_err_t result;
	
	result = rt_mb_recv(pcRxMail, (rt_ubase_t *)mail, timeout);

	return result;
}



rt_err_t send_pc_mail(pcMailDef *mail)
{
	rt_err_t result;

	result = rt_mb_send(pcTxMail, (rt_ubase_t)mail);
	if(result != RT_EOK)
	{
    LOG_E("send pc mail fail");
		rt_free(mail);
	}

	return result;
}

static void pc_cmd_advMode_process(pcMailDef *mail)
{
  bleMailDef *bleMail;
  rt_err_t    result;

  bleMail = rt_calloc(1, sizeof(*bleMail));
  RT_ASSERT(bleMail);

  //填充蓝牙报文数据
  bleMail->cmd     = PC_CMD_SET_MODE_REQ;
  bleMail->outtime = NET_RX_MSG_OUTTIME;
  bleMail->msgLen  = sizeof(advSetModeReqDef);
  bleMail->msg.proto.advSetModeReq.head[0] = MCU_ADV_HEAD1;
  bleMail->msg.proto.advSetModeReq.head[1] = MCU_ADV_HEAD2;
  bleMail->msg.proto.advSetModeReq.len = bleMail->msgLen;
  bleMail->msg.proto.advSetModeReq.cmd = bleMail->cmd; 
  bleMail->msg.proto.advSetModeReq.ID[0] = mail->msg.proto.mcuSetModeReq.id[0];
  bleMail->msg.proto.advSetModeReq.ID[1] = mail->msg.proto.mcuSetModeReq.id[1];
  bleMail->msg.proto.advSetModeReq.mode = mail->msg.proto.mcuSetModeReq.mode;
  rt_uint16_t crc = CRC16_MODBUS(bleMail->msg.buf,bleMail->msgLen-2);
  uint16_to_str(crc, &(bleMail->msg.buf[bleMail->msgLen-2]));

  result = send_ble_mail(bleMail);
  if(result != RT_EOK)//发送失败
  {
    pcMailDef *pcAckMail;

    LOG_E("send PC_CMD_SET_MODE_REQ Fail");
    rt_free(bleMail);

    //应答服务器
    pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
    RT_ASSERT(pcAckMail);

    pcAckMail->cmd = PC_CMD_SET_MODE_ACK;
    pcAckMail->outtime = NET_RX_MSG_OUTTIME;
    pcAckMail->msgLen = sizeof(mcuSetModeAckDef);
    pcAckMail->msg.proto.mcuSetModeAck.head[0] = PROTOCOL_HEAD1;
    pcAckMail->msg.proto.mcuSetModeAck.head[1] = PROTOCOL_HEAD2;
    pcAckMail->msg.proto.mcuSetModeAck.cmd = pcAckMail->cmd;
    pcAckMail->msg.proto.mcuSetModeAck.len = pcAckMail->msgLen;
    pcAckMail->msg.proto.boudnDevAck.result = 1;
    rt_uint16_t crc = CRC16_MODBUS(pcAckMail->msg.buf,pcAckMail->msgLen-2);
    uint16_to_str(crc, &(pcAckMail->msg.buf[pcAckMail->msgLen-2]));

    send_pc_mail(pcAckMail);//发送应答
    return ;
  }

  //等待邮件
  bleMailDef *rbleMail;

  rbleMail = rt_calloc(1,sizeof(*rbleMail));
  RT_ASSERT(rbleMail);
  
  result = ble_recv_mail(rbleMail,RT_NULL,ADV_CMD_SET_MODE_ACK,BLE_ACK_OUTIME);
  if(result == RT_EOK)//有收到应答
  {
    //保存到设备列表
    //应答PC
    pcMailDef *pcAckMail;

    pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
    RT_ASSERT(pcAckMail);

    LOG_I("ADV_CMD_SET_MODE_ACK OK result=%d",
          rbleMail->msg.proto.advSetModeAck.result);

    pcAckMail->cmd = PC_CMD_SET_MODE_ACK;
    pcAckMail->outtime = NET_RX_MSG_OUTTIME;
    pcAckMail->msgLen = sizeof(mcuSetModeAckDef);
    pcAckMail->msg.proto.mcuSetModeAck.head[0] = PROTOCOL_HEAD1;
    pcAckMail->msg.proto.mcuSetModeAck.head[1] = PROTOCOL_HEAD2;
    pcAckMail->msg.proto.mcuSetModeAck.cmd = pcAckMail->cmd;
    pcAckMail->msg.proto.mcuSetModeAck.len = pcAckMail->msgLen;
    pcAckMail->msg.proto.mcuSetModeAck.result = rbleMail->msg.proto.advSetModeAck.result;
    rt_uint16_t crc = CRC16_MODBUS(pcAckMail->msg.buf,pcAckMail->msgLen-2);
    uint16_to_str(crc, &(pcAckMail->msg.buf[pcAckMail->msgLen-2]));

    send_pc_mail(pcAckMail);//发送应答
  }
  else//发送失败
  {
    pcMailDef *pcAckMail;
    
    //应答服务器
    pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
    RT_ASSERT(pcAckMail);

    pcAckMail->cmd = PC_CMD_SET_MODE_ACK;
    pcAckMail->outtime = NET_RX_MSG_OUTTIME;
    pcAckMail->msgLen = sizeof(mcuSetModeAckDef);
    pcAckMail->msg.proto.mcuSetModeAck.head[0] = PROTOCOL_HEAD1;
    pcAckMail->msg.proto.mcuSetModeAck.head[1] = PROTOCOL_HEAD2;
    pcAckMail->msg.proto.mcuSetModeAck.cmd = pcAckMail->cmd;
    pcAckMail->msg.proto.mcuSetModeAck.len = pcAckMail->msgLen;
    pcAckMail->msg.proto.mcuSetModeAck.result = 1;
    rt_uint16_t crc = CRC16_MODBUS(pcAckMail->msg.buf,pcAckMail->msgLen-2);
    uint16_to_str(crc, &(pcAckMail->msg.buf[pcAckMail->msgLen-2]));

    send_pc_mail(pcAckMail);//发送应答
  }

  rt_free(rbleMail);
}


static void pc_cmd_bleDevSleep_process(pcMailDef *mail)
{
  bleMailDef *bleMail;
  rt_err_t    result;
  rt_uint8_t  mac[BLE_MAC_MAX];

  rt_memcpy(mac, mail->msg.proto.devSleepReq.mac, BLE_MAC_MAX);

  bleMail = rt_calloc(1, sizeof(*bleMail));
  RT_ASSERT(bleMail);

  //填充蓝牙报文数据
  bleMail->cmd     = BLE_CMD_DEVSLEEP_REQ;
  bleMail->outtime = NET_RX_MSG_OUTTIME;
  bleMail->msgLen  = sizeof(bleDevSleepReqDef);
  bleMail->msg.proto.devSleepReq.head[0] = MCU_BLE_HEAD1;
  bleMail->msg.proto.devSleepReq.head[1] = MCU_BLE_HEAD2;
  bleMail->msg.proto.devSleepReq.len = bleMail->msgLen;
  bleMail->msg.proto.devSleepReq.cmd = bleMail->cmd;
  bleMail->msg.proto.devSleepReq.sleep = mail->msg.proto.devSleepReq.sleep;
  rt_memcpy(&(bleMail->msg.proto.devSleepReq.mac[0]),
            &(mail->msg.proto.devSleepReq.mac[0]),
            MAC_MAX_SIZE);
  rt_memcpy(&(bleMail->msg.proto.devSleepReq.ssid[0]),
            &(mail->msg.proto.devSleepReq.ssid[0]),
            SSID_MAX_SIZE);
  rt_uint16_t crc = CRC16_MODBUS(bleMail->msg.buf,bleMail->msgLen-2);
  uint16_to_str(crc, &(bleMail->msg.buf[bleMail->msgLen-2]));

  result = send_ble_mail(bleMail);
  if(result != RT_EOK)//发送失败
  {
    pcMailDef *pcAckMail;
    
    rt_free(bleMail);

    //应答服务器
    pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
    RT_ASSERT(pcAckMail);

    pcAckMail->cmd = PC_CMD_DEVSLEEP_ACK;
    pcAckMail->outtime = NET_RX_MSG_OUTTIME;
    pcAckMail->msgLen = sizeof(devSleepAckDef);//PC休眠设置应答
    pcAckMail->msg.proto.devSleepAck.head[0] = PROTOCOL_HEAD1;
    pcAckMail->msg.proto.devSleepAck.head[1] = PROTOCOL_HEAD2;
    pcAckMail->msg.proto.devSleepAck.cmd = pcAckMail->cmd;
    pcAckMail->msg.proto.devSleepAck.len = pcAckMail->msgLen;
    pcAckMail->msg.proto.devSleepAck.result = 1;
    rt_uint16_t crc = CRC16_MODBUS(pcAckMail->msg.buf,pcAckMail->msgLen-2);
    uint16_to_str(crc, &(pcAckMail->msg.buf[pcAckMail->msgLen-2]));

    send_pc_mail(pcAckMail);//发送应答
    return ;
  }

  //等待邮件
  bleMailDef *rbleMail;

  rbleMail = rt_calloc(1,sizeof(*rbleMail));
  RT_ASSERT(rbleMail);
  
  result = ble_recv_mail(rbleMail,mac,BLE_CMD_DEVSLEEP_ACK,BLE_ACK_OUTIME);
  if(result == RT_EOK)//有收到应答
  {
    //保存到设备列表
    //应答PC
    pcMailDef *pcAckMail;

    pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
    RT_ASSERT(pcAckMail);

    pcAckMail->cmd = PC_CMD_DEVSLEEP_ACK;
    pcAckMail->outtime = NET_RX_MSG_OUTTIME;
    pcAckMail->msgLen = sizeof(devSleepAckDef);
    pcAckMail->msg.proto.devSleepAck.head[0] = PROTOCOL_HEAD1;
    pcAckMail->msg.proto.devSleepAck.head[1] = PROTOCOL_HEAD2;
    pcAckMail->msg.proto.devSleepAck.cmd = pcAckMail->cmd;
    pcAckMail->msg.proto.devSleepAck.len = pcAckMail->msgLen;
    pcAckMail->msg.proto.devSleepAck.result = rbleMail->msg.proto.devSleepAck.result;
    rt_uint16_t crc = CRC16_MODBUS(pcAckMail->msg.buf,pcAckMail->msgLen-2);
    uint16_to_str(crc, &(pcAckMail->msg.buf[pcAckMail->msgLen-2]));

    send_pc_mail(pcAckMail);//发送应答
  }
  else//发送失败
  {
    pcMailDef *pcAckMail;
    
    //应答服务器
    pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
    RT_ASSERT(pcAckMail);

    pcAckMail->cmd = PC_CMD_DEVSLEEP_ACK;
    pcAckMail->outtime = NET_RX_MSG_OUTTIME;
    pcAckMail->msgLen = sizeof(devSleepAckDef);
    pcAckMail->msg.proto.devSleepAck.head[0] = PROTOCOL_HEAD1;
    pcAckMail->msg.proto.devSleepAck.head[1] = PROTOCOL_HEAD2;
    pcAckMail->msg.proto.devSleepAck.cmd = pcAckMail->cmd;
    pcAckMail->msg.proto.devSleepAck.len = pcAckMail->msgLen;
    pcAckMail->msg.proto.devSleepAck.result = 1;
    rt_uint16_t crc = CRC16_MODBUS(pcAckMail->msg.buf,pcAckMail->msgLen-2);
    uint16_to_str(crc, &(pcAckMail->msg.buf[pcAckMail->msgLen-2]));

    send_pc_mail(pcAckMail);//发送应答
  }
  rt_free(rbleMail);
}

static void save_ble_to_file(rt_uint8_t *name,rt_uint8_t *mac,rt_uint8_t bound)
{
  if(bound)
  {
    add_ble_info((const char *)name, (const uint8_t *)mac);
  }
  else
  {
    delete_ble_info(mac);
  }
  print_ble_info();
  save_bleInfo();
}

static void pc_cmd_boundev_process(pcMailDef *mail)
{
  bleMailDef *bleMail;
  rt_err_t    result;
  rt_uint8_t  bound;//绑定状态
  rt_uint8_t  mac[BLE_MAC_MAX];

  rt_memcpy(mac, mail->msg.proto.boundDevReq.mac, BLE_MAC_MAX);
  bound = mail->msg.proto.boundDevReq.bound;

  bleMail = rt_calloc(1, sizeof(*bleMail));
  RT_ASSERT(bleMail);

  //填充蓝牙报文数据
  bleMail->cmd     = PC_CMD_BOUNDDEV_REQ;
  bleMail->outtime = NET_RX_MSG_OUTTIME;
  bleMail->msgLen  = sizeof(bleBoundDevReqDef);
  bleMail->msg.proto.boundDevReq.head[0] = MCU_BLE_HEAD1;
  bleMail->msg.proto.boundDevReq.head[1] = MCU_BLE_HEAD2;
  bleMail->msg.proto.boundDevReq.len = bleMail->msgLen;
  bleMail->msg.proto.boundDevReq.cmd = bleMail->cmd;
  rt_memcpy(&(bleMail->msg.proto.boundDevReq.mac[0]),
            &(mail->msg.proto.boundDevReq.mac[0]),
            MAC_MAX_SIZE);
  rt_memcpy(&(bleMail->msg.proto.boundDevReq.ssid[0]),
            &(mail->msg.proto.boundDevReq.ssid[0]),
            SSID_MAX_SIZE);
  bleMail->msg.proto.boundDevReq.bound = mail->msg.proto.boundDevReq.bound;
  rt_memcpy(bleMail->msg.proto.boundDevReq.id, mail->msg.proto.boundDevReq.id, 2);
  rt_uint16_t crc = CRC16_MODBUS(bleMail->msg.buf,bleMail->msgLen-2);
  uint16_to_str(crc, &(bleMail->msg.buf[bleMail->msgLen-2]));

  result = send_ble_mail(bleMail);
  if(result != RT_EOK)//发送失败
  {
    pcMailDef *pcAckMail;
    
    rt_free(bleMail);

    //应答服务器
    pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
    RT_ASSERT(pcAckMail);

    pcAckMail->cmd = PC_CMD_BOUNDDEV_ACK;
    pcAckMail->outtime = NET_RX_MSG_OUTTIME;
    pcAckMail->msgLen = sizeof(boundDevAckDef);
    pcAckMail->msg.proto.boudnDevAck.head[0] = PROTOCOL_HEAD1;
    pcAckMail->msg.proto.boudnDevAck.head[1] = PROTOCOL_HEAD2;
    pcAckMail->msg.proto.boudnDevAck.cmd = pcAckMail->cmd;
    pcAckMail->msg.proto.boudnDevAck.len = pcAckMail->msgLen;
    rt_memcpy(&(pcAckMail->msg.proto.boudnDevAck.mac[0]),
            &(mail->msg.proto.boundDevReq.mac[0]),
            MAC_MAX_SIZE);
    rt_memcpy(&(pcAckMail->msg.proto.boudnDevAck.ssid[0]),
            &(mail->msg.proto.boundDevReq.ssid[0]),
            SSID_MAX_SIZE);
    pcAckMail->msg.proto.boudnDevAck.result = 1;
    rt_uint16_t crc = CRC16_MODBUS(pcAckMail->msg.buf,pcAckMail->msgLen-2);
    uint16_to_str(crc, &(pcAckMail->msg.buf[pcAckMail->msgLen-2]));

    send_pc_mail(pcAckMail);//发送应答
    return ;
  }

  //等待邮件
  bleMailDef *rbleMail;

  rbleMail = rt_calloc(1,sizeof(*rbleMail));
  RT_ASSERT(rbleMail);
  
  result = ble_recv_mail(rbleMail,mac,BLE_CMD_BOUNDDEV_ACK,BLE_ACK_OUTIME);
  if(result == RT_EOK)//有收到应答
  {
    //应答PC
    pcMailDef *pcAckMail;

    LOG_I("BLE_CMD_BOUNDDEV_ACK result=%d",rbleMail->msg.proto.boudnDevAck.result);

    pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
    RT_ASSERT(pcAckMail);

    pcAckMail->cmd = PC_CMD_BOUNDDEV_ACK;
    pcAckMail->outtime = NET_RX_MSG_OUTTIME;
    pcAckMail->msgLen = sizeof(boundDevAckDef);
    pcAckMail->msg.proto.boudnDevAck.head[0] = PROTOCOL_HEAD1;
    pcAckMail->msg.proto.boudnDevAck.head[1] = PROTOCOL_HEAD2;
    pcAckMail->msg.proto.boudnDevAck.cmd = pcAckMail->cmd;
    pcAckMail->msg.proto.boudnDevAck.len = pcAckMail->msgLen;
    rt_memcpy(&(pcAckMail->msg.proto.boudnDevAck.mac[0]),
            &(rbleMail->msg.proto.boudnDevAck.mac[0]),
            MAC_MAX_SIZE);
    rt_memcpy(&(pcAckMail->msg.proto.boudnDevAck.ssid[0]),
            &(rbleMail->msg.proto.boudnDevAck.ssid[0]),
            SSID_MAX_SIZE);
    pcAckMail->msg.proto.boudnDevAck.result = rbleMail->msg.proto.boudnDevAck.result;

    if(pcAckMail->msg.proto.boudnDevAck.result == 0)
    {
      //保存到设备列表
      save_ble_to_file(pcAckMail->msg.proto.boudnDevAck.ssid,
                       pcAckMail->msg.proto.boudnDevAck.mac,
                       bound);
    }
    rt_uint16_t crc = CRC16_MODBUS(pcAckMail->msg.buf,pcAckMail->msgLen-2);
    uint16_to_str(crc, &(pcAckMail->msg.buf[pcAckMail->msgLen-2]));

    send_pc_mail(pcAckMail);//发送应答
  }
  else //发送超时失败
  {
    pcMailDef *pcAckMail;
    
    //应答服务器
    pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
    RT_ASSERT(pcAckMail);

    pcAckMail->cmd = PC_CMD_BOUNDDEV_ACK;
    pcAckMail->outtime = NET_RX_MSG_OUTTIME;
    pcAckMail->msgLen = sizeof(boundDevAckDef);
    pcAckMail->msg.proto.boudnDevAck.head[0] = PROTOCOL_HEAD1;
    pcAckMail->msg.proto.boudnDevAck.head[1] = PROTOCOL_HEAD2;
    pcAckMail->msg.proto.boudnDevAck.cmd = pcAckMail->cmd;
    pcAckMail->msg.proto.boudnDevAck.len = pcAckMail->msgLen;
    rt_memcpy(&(pcAckMail->msg.proto.boudnDevAck.mac[0]),
            &(mail->msg.proto.boundDevReq.mac[0]),
            MAC_MAX_SIZE);
    rt_memcpy(&(pcAckMail->msg.proto.boudnDevAck.ssid[0]),
            &(mail->msg.proto.boundDevReq.ssid[0]),
            SSID_MAX_SIZE);
    pcAckMail->msg.proto.boudnDevAck.result = 1;
    rt_uint16_t crc = CRC16_MODBUS(pcAckMail->msg.buf,pcAckMail->msgLen-2);
    uint16_to_str(crc, &(pcAckMail->msg.buf[pcAckMail->msgLen-2]));

    send_pc_mail(pcAckMail);//发送应答
  }
  
  rt_free(rbleMail);
}

static void pc_cmd_devCapReq_process(pcMailDef *mail)
{
  bleMailDef *bleMail;
  rt_err_t    result;
  rt_uint8_t  mac[BLE_MAC_MAX];

  rt_memcpy(mac, mail->msg.proto.devCapReq.mac, BLE_MAC_MAX);

  bleMail = rt_calloc(1, sizeof(*bleMail));
  RT_ASSERT(bleMail);

  //填充蓝牙报文数据
  bleMail->cmd     = BLE_CMD_DEVCAP_REQ;
  bleMail->outtime = NET_RX_MSG_OUTTIME;
  bleMail->msgLen  = sizeof(bleDevCapReqDef);//蓝牙通知从设备测信号请求
  bleMail->msg.proto.devCapReq.head[0] = MCU_BLE_HEAD1;
  bleMail->msg.proto.devCapReq.head[1] = MCU_BLE_HEAD2;
  bleMail->msg.proto.devCapReq.len = bleMail->msgLen;
  bleMail->msg.proto.devCapReq.cmd = bleMail->cmd;
  rt_memcpy(&(bleMail->msg.proto.devCapReq.mac[0]),
            &(mail->msg.proto.devCapReq.mac[0]),
            MAC_MAX_SIZE);
  rt_memcpy(&(bleMail->msg.proto.devCapReq.ssid[0]),
            &(mail->msg.proto.devCapReq.ssid[0]),
            SSID_MAX_SIZE);
  rt_uint16_t crc = CRC16_MODBUS(bleMail->msg.buf,bleMail->msgLen-2);
  uint16_to_str(crc, &(bleMail->msg.buf[bleMail->msgLen-2]));

  result = send_ble_mail(bleMail);
  if(result != RT_EOK)//发送失败
  {
    pcMailDef *pcAckMail;
    
    rt_free(bleMail);

    //应答服务器
    pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
    RT_ASSERT(pcAckMail);

    pcAckMail->cmd = PC_CMD_DEVCAP_ACK;
    pcAckMail->outtime = NET_RX_MSG_OUTTIME;
    pcAckMail->msgLen = sizeof(devCapAckDef);//PC休眠设置应答
    pcAckMail->msg.proto.devCapAck.head[0] = PROTOCOL_HEAD1;
    pcAckMail->msg.proto.devCapAck.head[1] = PROTOCOL_HEAD2;
    pcAckMail->msg.proto.devCapAck.cmd = pcAckMail->cmd;
    pcAckMail->msg.proto.devCapAck.len = pcAckMail->msgLen;
    pcAckMail->msg.proto.devCapAck.rssi = 0;
    pcAckMail->msg.proto.devCapAck.result = 1;
    rt_uint16_t crc = CRC16_MODBUS(pcAckMail->msg.buf,pcAckMail->msgLen-2);
    uint16_to_str(crc, &(pcAckMail->msg.buf[pcAckMail->msgLen-2]));

    send_pc_mail(pcAckMail);//发送应答
    return ;
  }

  //等待邮件
  bleMailDef *rbleMail;

  rbleMail = rt_calloc(1,sizeof(*rbleMail));
  RT_ASSERT(rbleMail);
  
  result = ble_recv_mail(rbleMail,mac,BLE_CMD_DEVCAP_ACK,BLE_ACK_OUTIME);
  if(result == RT_EOK)//有收到应答
  {
    //保存到设备列表
    //应答PC
    pcMailDef *pcAckMail;

    pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
    RT_ASSERT(pcAckMail);

    pcAckMail->cmd = PC_CMD_DEVCAP_ACK;
    pcAckMail->outtime = NET_RX_MSG_OUTTIME;
    pcAckMail->msgLen = sizeof(devCapAckDef);
    pcAckMail->msg.proto.devCapAck.head[0] = PROTOCOL_HEAD1;
    pcAckMail->msg.proto.devCapAck.head[1] = PROTOCOL_HEAD2;
    pcAckMail->msg.proto.devCapAck.cmd = pcAckMail->cmd;
    pcAckMail->msg.proto.devCapAck.len = pcAckMail->msgLen;
    rt_memcpy(&(pcAckMail->msg.proto.devCapAck.ssid[0]), 
              &(rbleMail->msg.proto.devCapAck.ssid[0]), 
              pcAckMail->msgLen - MSG_FIX_SIZE);
    rt_uint16_t crc = CRC16_MODBUS(pcAckMail->msg.buf,pcAckMail->msgLen-2);
    uint16_to_str(crc, &(pcAckMail->msg.buf[pcAckMail->msgLen-2]));
    send_pc_mail(pcAckMail);//发送应答
  }
  else//发送失败
  {
    pcMailDef *pcAckMail;
    
    //应答服务器
    pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
    RT_ASSERT(pcAckMail);

    pcAckMail->cmd = PC_CMD_DEVCAP_ACK;
    pcAckMail->outtime = NET_RX_MSG_OUTTIME;
    pcAckMail->msgLen = sizeof(devCapAckDef);
    pcAckMail->msg.proto.devCapAck.head[0] = PROTOCOL_HEAD1;
    pcAckMail->msg.proto.devCapAck.head[1] = PROTOCOL_HEAD2;
    pcAckMail->msg.proto.devCapAck.cmd = pcAckMail->cmd;
    pcAckMail->msg.proto.devCapAck.len = pcAckMail->msgLen;
    pcAckMail->msg.proto.devCapAck.result = 2;
    rt_uint16_t crc = CRC16_MODBUS(pcAckMail->msg.buf,pcAckMail->msgLen-2);
    uint16_to_str(crc, &(pcAckMail->msg.buf[pcAckMail->msgLen-2]));

    send_pc_mail(pcAckMail);//发送应答
  }
  rt_free(rbleMail);
}


#if 0
static void pc_cmd_devStopCapReq_process(pcMailDef *mail)
{
  bleMailDef *bleMail;
  rt_err_t    result;

  bleMail = rt_calloc(1, sizeof(*bleMail));
  RT_ASSERT(bleMail);

  //填充蓝牙报文数据
  bleMail->cmd     = BLE_CMD_STOPCAP_REQ;
  bleMail->outtime = NET_RX_MSG_OUTTIME;
  bleMail->msgLen  = sizeof(bleDevStopCapReqDef);//蓝牙通知从设备测试陀螺仪数据
  bleMail->msg.proto.devStopCapReq.head[0] = MCU_BLE_HEAD1;
  bleMail->msg.proto.devStopCapReq.head[1] = MCU_BLE_HEAD2;
  bleMail->msg.proto.devStopCapReq.len = bleMail->msgLen;
  bleMail->msg.proto.devStopCapReq.cmd = bleMail->cmd;
  rt_memcpy(&(bleMail->msg.proto.devStopCapReq.mac[0]),
            &(mail->msg.proto.devStopCapReq.mac[0]),
            MAC_MAX_SIZE);
  rt_memcpy(&(bleMail->msg.proto.devStopCapReq.ssid[0]),
            &(mail->msg.proto.devStopCapReq.ssid[0]),
            SSID_MAX_SIZE);

  result = send_ble_mail(bleMail);
  if(result != RT_EOK)//发送失败
  {
    pcMailDef *pcAckMail;
    
    rt_free(bleMail);

    //应答服务器
    pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
    RT_ASSERT(pcAckMail);

    pcAckMail->cmd = PC_CMD_STOPCAP_ACK;
    pcAckMail->outtime = NET_RX_MSG_OUTTIME;
    pcAckMail->msgLen = sizeof(devStopCapAckDef);//PC陀螺仪应答数据
    pcAckMail->msg.proto.devStopCapAck.head[0] = PROTOCOL_HEAD1;
    pcAckMail->msg.proto.devStopCapAck.head[1] = PROTOCOL_HEAD2;
    pcAckMail->msg.proto.devStopCapAck.cmd = pcAckMail->cmd;
    pcAckMail->msg.proto.devStopCapAck.len = pcAckMail->msgLen;
    pcAckMail->msg.proto.devStopCapAck.result = 1;//发送失败

    send_pc_mail(pcAckMail);//发送应答
    return ;
  }

  //等待邮件
  bleMailDef *rbleMail;

  rbleMail = rt_calloc(1,sizeof(*rbleMail));
  RT_ASSERT(rbleMail);
  
  result = ble_recv_mail(&rbleMail,BLE_CMD_STOPCAP_ACK,BLE_ACK_OUTIME);
  if(result == RT_EOK)//有收到应答
  {
    //保存到设备列表
    //应答PC
    pcMailDef *pcAckMail;

    pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
    RT_ASSERT(pcAckMail);

    pcAckMail->cmd = PC_CMD_STOPCAP_ACK;
    pcAckMail->outtime = NET_RX_MSG_OUTTIME;
    pcAckMail->msgLen = sizeof(devStopCapAckDef);
    pcAckMail->msg.proto.devStopCapAck.head[0] = PROTOCOL_HEAD1;
    pcAckMail->msg.proto.devStopCapAck.head[1] = PROTOCOL_HEAD2;
    pcAckMail->msg.proto.devStopCapAck.cmd = pcAckMail->cmd;
    pcAckMail->msg.proto.devStopCapAck.len = pcAckMail->msgLen;
    rt_memcpy(&(pcAckMail->msg.proto.devStopCapAck.ssid[0]), 
              &(rbleMail->msg.proto.devStopCapAck.ssid[0]), 
              pcAckMail->msgLen - 6);
    send_pc_mail(pcAckMail);//发送应答
  }
  else//发送失败
  {
    pcMailDef *pcAckMail;
    
    //应答服务器
    pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
    RT_ASSERT(pcAckMail);

    pcAckMail->cmd = PC_CMD_STOPCAP_ACK;
    pcAckMail->outtime = NET_RX_MSG_OUTTIME;
    pcAckMail->msgLen = sizeof(devStopCapAckDef);
    pcAckMail->msg.proto.devStopCapAck.head[0] = PROTOCOL_HEAD1;
    pcAckMail->msg.proto.devStopCapAck.head[1] = PROTOCOL_HEAD2;
    pcAckMail->msg.proto.devStopCapAck.cmd = pcAckMail->cmd;
    pcAckMail->msg.proto.devStopCapAck.len = pcAckMail->msgLen;
    pcAckMail->msg.proto.devStopCapAck.result = 2;

    send_pc_mail(pcAckMail);//发送应答
  }
}
#endif

static void pc_cmd_getBoundDevReq_process(pcMailDef *mail)
{
  pcMailDef  *pcAckMail;
  rt_err_t    result = RT_ERROR;
  rt_uint16_t pos;
  rt_uint8_t  ackResult;

  pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
  RT_ASSERT(pcAckMail);


  pos = str_to_uint16(mail->msg.proto.getBoundDevReq.pos);

  if(pos < BLE_MAX_NUM)
  {
    ackResult = get_ble_info(pos,pcAckMail->msg.proto.getBoundDevAck.mac,
                             pcAckMail->msg.proto.getBoundDevAck.ssid,
                             pcAckMail->msg.proto.getBoundDevAck.num);
  }    
  else
  {
    ackResult = 1;
  }
  //应答服务器
  
  pcAckMail->cmd = PC_CMD_GETDEV_ACK;
  pcAckMail->outtime = NET_RX_MSG_OUTTIME;
  pcAckMail->msgLen = sizeof(getBoundDevAckDef);//PC陀螺仪应答数据
  pcAckMail->msg.proto.getBoundDevAck.head[0] = PROTOCOL_HEAD1;
  pcAckMail->msg.proto.getBoundDevAck.head[1] = PROTOCOL_HEAD2;
  pcAckMail->msg.proto.getBoundDevAck.cmd = pcAckMail->cmd;
  pcAckMail->msg.proto.getBoundDevAck.len = pcAckMail->msgLen;
  pcAckMail->msg.proto.getBoundDevAck.result = ackResult;//发送失败
  rt_uint16_t crc = CRC16_MODBUS(pcAckMail->msg.buf,pcAckMail->msgLen-2);
  uint16_to_str(crc, &(pcAckMail->msg.buf[pcAckMail->msgLen-2])); 
  send_pc_mail(pcAckMail);//发送应答

  if(result != RT_EOK)//发送失败
  {
    
    rt_free(pcAckMail);
    LOG_E("pc_cmd_getBoundDevReq_process ack fail");
    return ;
  }
}


static void pc_cmd_getHostInfo_process(pcMailDef *mail)
{
  pcMailDef  *pcAckMail;
  rt_err_t    result = RT_ERROR;
  rt_uint16_t id;

  pcAckMail = rt_calloc(1, sizeof(*pcAckMail));
  RT_ASSERT(pcAckMail);


  id = str_to_uint16(mail->msg.proto.getHostInfoReq.id);

  if(id > 0)//修改ID
  {
    bleInfo_init();
    ble_info.id = id;
    save_bleInfo();
  }    
  //应答服务器
  
  pcAckMail->cmd = PC_CMD_GETHOSTINFO_ACK;
  pcAckMail->outtime = NET_RX_MSG_OUTTIME;
  pcAckMail->msgLen = sizeof(getHostInfoAckDef);//PC陀螺仪应答数据
  pcAckMail->msg.proto.getHostInfoAck.head[0] = PROTOCOL_HEAD1;
  pcAckMail->msg.proto.getHostInfoAck.head[1] = PROTOCOL_HEAD2;
  pcAckMail->msg.proto.getHostInfoAck.cmd = pcAckMail->cmd;
  pcAckMail->msg.proto.getHostInfoAck.len = pcAckMail->msgLen;
  pcAckMail->msg.proto.getHostInfoAck.result = 0;//发送失败

  uint16_to_str(id,pcAckMail->msg.proto.getHostInfoAck.id);
  uint16_to_str(ble_info.num_devices, pcAckMail->msg.proto.getHostInfoAck.bleNum);
  rt_uint16_t crc = CRC16_MODBUS(pcAckMail->msg.buf,pcAckMail->msgLen-2);
  uint16_to_str(crc, &(pcAckMail->msg.buf[pcAckMail->msgLen-2])); 
  send_pc_mail(pcAckMail);//发送应答

  if(result != RT_EOK)//发送失败
  {
    
    rt_free(pcAckMail);
    LOG_E("pc_cmd_getBoundDevReq_process ack fail");
    return ;
  }
}

static void pc_mail_process(void)
{
    pcMailDef *mail;
    
    rt_err_t result = rt_mb_recv(pcRxMail, (rt_ubase_t *)&mail, 100);
    if(result == RT_EOK)
    {
        switch(mail->msg.buf[MSG_CMD_POS])
        {
            case PC_CMD_SET_MODE_REQ://设置广播主机
            {
              LOG_I("PC_CMD_SET_MODE_REQ");
              pc_cmd_advMode_process(mail);
              break;
            }
            case PC_CMD_BOUNDDEV_REQ://绑定设备请求
            {
              LOG_I("PC_CMD_BOUNDDEV_REQ");
              pc_cmd_boundev_process(mail);
              break;
            }
            case PC_CMD_DEVSLEEP_REQ://设置设备休眠
            {
              LOG_I("PC_CMD_DEVSLEEP_REQ");
              pc_cmd_bleDevSleep_process(mail);
              break;
            }
            case PC_CMD_DEVCAP_REQ:
            {
              LOG_I("PC_CMD_DEVCAP_REQ");
              pc_cmd_devCapReq_process(mail);
              break;
            }
            case PC_CMD_GETDEV_REQ:
            {
              LOG_I("PC_CMD_GETDEV_REQ");
              pc_cmd_getBoundDevReq_process(mail);
              break;
            }
            case PC_CMD_GETHOSTINFO_REQ:
            {
              LOG_I("PC_CMD_GETHOSTINFO_REQ");
              pc_cmd_getHostInfo_process(mail);
              break;
            }
            default:
            {
              LOG_E("unknow cmd %d", mail->msg.buf[MSG_CMD_POS]);
              break;
            }

        }
    }
}

static void pc_proto_thread(void *parameter)
{
  while(1)
  {
    //处理接收到的PC消息
    pc_mail_process();

  }
}

static void pc_uart_recv_msg(void)
{
    rt_uint8_t ch;
    rt_uint8_t *buf = RT_NULL;
    rt_uint8_t outTime = 100;
    rt_uint8_t pos = 0;
    rt_uint8_t recvLen = 0;

    buf = rt_calloc(1, ADV_MSG_BUF);
    RT_ASSERT(buf != RT_NULL);

    while(outTime--)
    {
        int size;
        size =  rt_device_read(uartPC,0, &ch, 1);//读取一个字节
        if(size == 1)
        {
            buf[pos++] = ch;
            if(pos == 2)
            {
                if(buf[0] != PROTOCOL_HEAD1 || buf[1] != PROTOCOL_HEAD2)//收的到了头
                {
                    LOG_E("ADV uart read error!");
                    break;
                }
            }
            else if(pos ==3)
            {
              recvLen = buf[2];
              if(recvLen > sizeof(pcMsgDef))//长度错误
              {
                LOG_E("bleMsgDef recvLen is ERR");
                break;
              }
            }
            if((pos == recvLen)&&(recvLen != 0))//接收完成
            {
                rt_kprintf("PC%2d>>>",recvLen);
                show_hex_string(buf, recvLen);
                pcMailDef *mail;

                mail = rt_calloc(1, sizeof(*mail));
                RT_ASSERT(mail);

                rt_memcpy(mail->msg.buf, buf, recvLen);
                mail->cmd = buf[3];
                mail->msgLen = recvLen;
                mail->outtime = NET_RX_MSG_OUTTIME;
                rt_err_t result = rt_mb_send(pcRxMail, (rt_ubase_t)mail);
                if(result != RT_EOK)
                {
                  LOG_E("put pcRxMail fail !!!!!!!!!!");
                  rt_free(mail);
                  break;
                }
                else
                {
                  break;
                }
            }
        }
        else
        {
          rt_thread_mdelay(5);
        }

    }
    rt_free(buf);
}


static void pc_rx_thread(void *parameter)
{
  while(1)
  {
    rt_thread_mdelay(2);
    pc_uart_recv_msg();//负责接收数据
  }
}


static void pc_send_mail_process(void)
{
  rt_err_t result;
  pcMailDef *mail;

  result = rt_mb_recv(pcTxMail, (rt_ubase_t *)(&mail), 100);
  if(result == RT_EOK)
  {
    if(uartPC != RT_NULL)
    {
      rt_kprintf("PC%2d<<<",mail->msgLen);
      show_hex_string(mail->msg.buf, mail->msgLen);
      rt_size_t size = rt_device_write(uartPC, 0, mail->msg.buf, mail->msgLen);
      if(size != mail->msgLen)
      {
         LOG_E("write uart pc fail !!!!!");
      }
    }
    else
    {
      LOG_E("PC uart is none open");
    }
    rt_free(mail);//释放资源
  }
}

//处理发送给PC的报文
static void pc_tx_thread(void *parameter)
{
  while(1)
  {
    pc_send_mail_process();//负责发送数据给上位机
  }
}



void pc_proto_init(void)
{
    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;

    LOG_I("pc_proto_init");

    uartPC = rt_device_find(PC_UART_NAME);
    if (uartPC == RT_NULL)
    {
        LOG_E("uartPC device not found!");
        return;
    }
    rt_err_t result = rt_device_open(uartPC, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
    if (result != RT_EOK)
    {
        LOG_E("uartPC device open failed!");
        return;
    }
    
    config.baud_rate = BAUD_RATE_115200;
    result = rt_device_control(uartPC, RT_DEVICE_CTRL_CONFIG, &config);
    if (result != RT_EOK)
    {
        LOG_E("uartPC device config failed!");
        return;
    }

    pcRxMail = rt_mb_create("PCTX", 10, RT_IPC_FLAG_FIFO);
    RT_ASSERT(pcRxMail);

    pcTxMail = rt_mb_create("PCRX", 10, RT_IPC_FLAG_FIFO);
    RT_ASSERT(pcTxMail);

    rt_thread_t tid = rt_thread_create("pcpro", pc_proto_thread, RT_NULL,
                                       2048, RT_THREAD_PRIORITY_MAX - 2, 20);
    if (tid != NULL)
        rt_thread_startup(tid);

    tid = rt_thread_create("pcrx", pc_rx_thread, RT_NULL,
                                   2048, RT_THREAD_PRIORITY_MAX - 2, 20);
    if (tid != NULL)
    rt_thread_startup(tid);

    tid = rt_thread_create("pctx", pc_tx_thread, RT_NULL,
                                   2048, RT_THREAD_PRIORITY_MAX - 2, 20);
    if (tid != NULL)
    rt_thread_startup(tid);
}

//写一个函数模拟PC发送MCU切换ADV工作模式的报文
void testPCmsg(int argc,char **argv)
{
    pcMailDef *mail;
    rt_uint8_t mac[MAC_MAX_SIZE]={1,1,1,1,2,3};

    if(argc < 2)
    {
        rt_kprintf("Usage: %s <cmd>\n", argv[0]);
        return;
    }
    
    mail = rt_calloc(1, sizeof(*mail));
    RT_ASSERT(mail);

    switch(atoi(argv[1]))
    {
        case PC_CMD_REQPORTED_ACK:
            mail->msg.buf[2] = sizeof(mcuReporotedDataDef);
            break;
        case PC_CMD_SET_MODE_REQ:
            mail->msg.buf[2] = sizeof(mcuSetModeReqDef);
            mail->msg.proto.mcuSetModeReq.mode = atoi(argv[2]);
            uint16_to_str(123, mail->msg.proto.mcuSetModeReq.id);
            break;
        case PC_CMD_SET_MODE_ACK:
            mail->msg.buf[2] = sizeof(mcuSetModeAckDef);
            break;
        case PC_CMD_BOUNDDEV_REQ:
            mail->msg.buf[2] = sizeof(boundDevReqDef);
            mail->msg.proto.boundDevReq.id[1] = atoi(argv[2]);
            mac[5] = atoi(argv[3]);
            rt_memcpy(mail->msg.proto.boundDevReq.mac,mac,MAC_MAX_SIZE);
            break;
        case PC_CMD_BOUNDDEV_ACK:
            mail->msg.buf[2] = sizeof(boundDevAckDef);
            break;
        case PC_CMD_DEVSLEEP_REQ:
            mail->msg.buf[2] = sizeof(devSleepReqDef);
            break;
        case PC_CMD_DEVSLEEP_ACK:
            mail->msg.buf[2] = sizeof(devSleepAckDef);
            break;
        case 	PC_CMD_DEVCAP_REQ:
            mail->msg.buf[2] = sizeof(devCapReqDef);
            break;
        case 	PC_CMD_DEVCAP_ACK:
            mail->msg.buf[2] = sizeof(devCapAckDef);
            break;
        case PC_CMD_GETDEV_REQ:
            mail->msg.buf[2] = sizeof(devStopCapReqDef);
            break;
        case PC_CMD_GETDEV_ACK:
            mail->msg.buf[2] = sizeof(devStopCapAckDef);
            break;
        default:
            rt_kprintf("cmd is none\n");
            return;
            break;
    }

    mail->msg.buf[0] = PROTOCOL_HEAD1;
    mail->msg.buf[1] = PROTOCOL_HEAD2;
    mail->msg.buf[3] = atoi(argv[1]);
    mail->msgLen = mail->msg.buf[2];
    mail->outtime = NET_RX_MSG_OUTTIME;
    rt_uint16_t crc = CRC16_MODBUS(mail->msg.buf,mail->msgLen-2);
    uint16_to_str(crc, &(mail->msg.buf[mail->msgLen-2]));
    show_hex_string(mail->msg.buf, mail->msgLen);
    rt_kprintf("\r\n");
    rt_mb_send(pcRxMail, (rt_ubase_t)mail);
}
MSH_CMD_EXPORT(testPCmsg,"模拟测试PC发送MCU报文");



